/**
 * 处理企业微信转交
 */
import { getLogger, Service } from '@gnlab/utils'
import { Subject } from 'rxjs'
import type { Services } from '@/services'
import { API } from '@/services/common/api'
import type { RecvMessage } from '@/services/common/qywx-mqtt/protocol'
import type { RawQywxTransfer, QywxTransfer, QywxInfo } from './types'
import { formatQywxTransfer } from './types'

const logger = getLogger('services/qywxs/transfer')

export class QywxTransfers extends Service<Services> {
  private get communicate() {
    return this.services.mqtt.communicate
  }
  private get auth() {
    return this.services.auth
  }
  private get account() {
    return this.services.auth.account$.value!
  }
  private get qywxs() {
    return this.services.qywxs
  }

  registered() {
    void this.auth.bizAccountIds.then(() => {
      this.initTransferHandler()
    })
  }

  /**
   * 推送“接收到企业微信”的消息（包括转给他人或他人转过来；操作者可能是拥有企业微信的员工，或者管理员）
   */
  transfered = new Subject<QywxTransfer>()

  /**
   * 监听企业微信转交消息
   */
  protected initTransferHandler() {
    this.communicate.manage<RawQywxTransfer>(60004).subscribe(this.onTransfer.bind(this))
  }

  protected onTransfer(message: RecvMessage<RawQywxTransfer>) {
    const transfer = formatQywxTransfer(message.data)
    logger.info('接收到企业微信转交消息', transfer)
    this.transfered.next(transfer)

    // 通过接口拉取最新的企业微信列表，列表里包含了每个企业微信的信息，就不用这里想办法获取这些信息了。
    void this.qywxs.loadQywxs()
  }

  /**
   * 将企业微信转交给另一个账号
   * 成功返回 true；失败返回错误信息字符串
   */
  async transfer(
    qywxs: QywxInfo[],
    toAccount: { id: string; name: string },
    fromAccount?: { id: string; name: string },
  ) {
    const res = await API('/Transfer/TransferEnterpriseWechat', {
      data: {
        WxIds: qywxs.map(v => v.wxid),
        WxNames: qywxs.map(v => v.friendlyFullName),
        FromUserId: fromAccount?.id ?? this.account.id,
        FromUserName: fromAccount?.name ?? this.account.name,
        ToUserId: toAccount.id,
        ToUserName: toAccount.name,
      },
    })

    if (res.success) {
      return true
    } else {
      return `转交失败：${res.error}`
    }
  }
}
